package service

import (
	"context"
	"fmt"
	"log"
	"strconv"

	"github.com/shopspring/decimal"
	"gorm.io/gorm"

	"gitee.com/wangshh_123/cross-pay-go/src/models"
)

// CardBalanceSyncService 卡片余额同步服务
type CardBalanceSyncService struct {
	db *gorm.DB
}

// NewCardBalanceSyncService 创建卡片余额同步服务
func NewCardBalanceSyncService(db *gorm.DB) *CardBalanceSyncService {
	return &CardBalanceSyncService{
		db: db,
	}
}

// SyncCardBalanceFromAPI 从API同步卡片余额到本地数据库
func (s *CardBalanceSyncService) SyncCardBalanceFromAPI(ctx context.Context, userID int64, platform string) error {
	// 获取用户的所有卡片
	var userCards []models.UserCard
	if err := s.db.Where("user_id = ? AND platform = ?", userID, platform).Find(&userCards).Error; err != nil {
		return fmt.Errorf("failed to get user cards: %v", err)
	}

	log.Printf("[CardBalanceSync] 开始同步用户 %d 的 %d 张卡片余额", userID, len(userCards))

	successCount := 0
	errorCount := 0

	for _, card := range userCards {
		// 调用API获取卡片详情
		cardBalance, err := s.getCardBalanceFromAPI(ctx, card.CardID, platform)
		if err != nil {
			log.Printf("[CardBalanceSync] 获取卡片 %s 余额失败: %v", card.CardID, err)
			errorCount++
			continue
		}

		// 更新本地数据库
		if err := s.db.Model(&card).Update("TotalTransferAmount", cardBalance).Error; err != nil {
			log.Printf("[CardBalanceSync] 更新卡片 %s 余额失败: %v", card.CardID, err)
			errorCount++
			continue
		}

		log.Printf("[CardBalanceSync] 卡片 %s 余额同步成功: %s", card.CardID, cardBalance.String())
		successCount++
	}

	log.Printf("[CardBalanceSync] 同步完成: 成功=%d, 失败=%d", successCount, errorCount)
	return nil
}

// getCardBalanceFromAPI 从API获取卡片余额
func (s *CardBalanceSyncService) getCardBalanceFromAPI(ctx context.Context, cardID string, platform string) (decimal.Decimal, error) {
	// 这里需要根据平台调用相应的API
	// 由于我们没有直接的API客户端，这里提供一个示例实现
	// 实际使用时需要根据具体的API接口来实现

	switch platform {
	case "photonpay":
		return s.getPhotonPayCardBalance(ctx, cardID)
	case "hlpay":
		return s.getHlPayCardBalance(ctx, cardID)
	default:
		return decimal.Zero, fmt.Errorf("unsupported platform: %s", platform)
	}
}

// getPhotonPayCardBalance 获取PhotonPay卡片余额
func (s *CardBalanceSyncService) getPhotonPayCardBalance(ctx context.Context, cardID string) (decimal.Decimal, error) {
	// 这里应该调用PhotonPay的API
	// 由于我们没有直接的API访问，这里返回一个示例值
	// 实际实现时需要调用真实的API
	return decimal.NewFromFloat(0), fmt.Errorf("PhotonPay API not implemented")
}

// getHlPayCardBalance 获取HlPay卡片余额
func (s *CardBalanceSyncService) getHlPayCardBalance(ctx context.Context, cardID string) (decimal.Decimal, error) {
	// 这里应该调用HlPay的API
	// 由于我们没有直接的API访问，这里返回一个示例值
	// 实际实现时需要调用真实的API
	return decimal.NewFromFloat(0), fmt.Errorf("HlPay API not implemented")
}

// SyncCardBalanceFromCardListAPI 从卡片列表API同步余额
func (s *CardBalanceSyncService) SyncCardBalanceFromCardListAPI(ctx context.Context, userID int64, platform string, apiResponse map[string]interface{}) error {
	// 解析API响应中的卡片数据
	data, ok := apiResponse["data"].(map[string]interface{})
	if !ok {
		return fmt.Errorf("invalid API response format")
	}

	cardListData, ok := data["data"].([]interface{})
	if !ok {
		return fmt.Errorf("invalid card list data format")
	}

	log.Printf("[CardBalanceSync] 开始从API响应同步 %d 张卡片余额", len(cardListData))

	successCount := 0
	errorCount := 0

	for _, cardData := range cardListData {
		cardMap, ok := cardData.(map[string]interface{})
		if !ok {
			log.Printf("[CardBalanceSync] 无效的卡片数据格式")
			errorCount++
			continue
		}

		cardID, ok := cardMap["cardId"].(string)
		if !ok {
			log.Printf("[CardBalanceSync] 卡片ID无效")
			errorCount++
			continue
		}

		// 获取卡片余额
		var cardBalance float64
		if balance, ok := cardMap["cardBalance"].(float64); ok {
			cardBalance = balance
		} else if balanceStr, ok := cardMap["cardBalance"].(string); ok {
			if parsed, err := strconv.ParseFloat(balanceStr, 64); err == nil {
				cardBalance = parsed
			} else {
				log.Printf("[CardBalanceSync] 卡片 %s 余额格式无效: %s", cardID, balanceStr)
				errorCount++
				continue
			}
		} else {
			log.Printf("[CardBalanceSync] 卡片 %s 余额字段缺失", cardID)
			errorCount++
			continue
		}

		// 更新本地数据库
		balanceDecimal := decimal.NewFromFloat(cardBalance)
		if err := s.db.Model(&models.UserCard{}).
			Where("card_id = ? AND user_id = ?", cardID, userID).
			Update("TotalTransferAmount", balanceDecimal).Error; err != nil {
			log.Printf("[CardBalanceSync] 更新卡片 %s 余额失败: %v", cardID, err)
			errorCount++
			continue
		}

		log.Printf("[CardBalanceSync] 卡片 %s 余额同步成功: %s", cardID, balanceDecimal.String())
		successCount++
	}

	log.Printf("[CardBalanceSync] 从API响应同步完成: 成功=%d, 失败=%d", successCount, errorCount)
	return nil
}

// GetDB 获取数据库连接
func (s *CardBalanceSyncService) GetDB() *gorm.DB {
	return s.db
}

// GetCardBalanceSummary 获取卡片余额统计
func (s *CardBalanceSyncService) GetCardBalanceSummary(ctx context.Context, userID int64) (map[string]interface{}, error) {
	var totalCards int64
	var totalBalance decimal.Decimal
	var zeroBalanceCards int64

	// 统计总卡片数
	if err := s.db.Model(&models.UserCard{}).Where("user_id = ?", userID).Count(&totalCards).Error; err != nil {
		return nil, fmt.Errorf("failed to count total cards: %v", err)
	}

	// 统计总余额
	if err := s.db.Model(&models.UserCard{}).
		Where("user_id = ?", userID).
		Select("COALESCE(SUM(TotalTransferAmount), 0) as total").
		Scan(&totalBalance).Error; err != nil {
		return nil, fmt.Errorf("failed to calculate total balance: %v", err)
	}

	// 统计余额为0的卡片数
	if err := s.db.Model(&models.UserCard{}).
		Where("user_id = ? AND TotalTransferAmount = ?", userID, decimal.Zero).
		Count(&zeroBalanceCards).Error; err != nil {
		return nil, fmt.Errorf("failed to count zero balance cards: %v", err)
	}

	// 按平台统计
	var platformStats []struct {
		Platform string          `json:"platform"`
		Count    int64           `json:"count"`
		Balance  decimal.Decimal `json:"balance"`
	}

	if err := s.db.Model(&models.UserCard{}).
		Where("user_id = ?", userID).
		Select("platform, COUNT(*) as count, COALESCE(SUM(TotalTransferAmount), 0) as balance").
		Group("platform").
		Scan(&platformStats).Error; err != nil {
		return nil, fmt.Errorf("failed to get platform stats: %v", err)
	}

	return map[string]interface{}{
		"totalCards":       totalCards,
		"totalBalance":     totalBalance.String(),
		"zeroBalanceCards": zeroBalanceCards,
		"platformStats":    platformStats,
	}, nil
}
